#include "arch_bloques_libres.h"

#define _TAM_ELEMENTO_		sizeof(unsigned int)

unsigned int ArchBloquesLibres::ERROR = UINT_MAX;

ArchBloquesLibres::ArchBloquesLibres(std::string &nombre, unsigned int tam_bloque):ArchControl(nombre, tam_bloque){
	
}

unsigned ArchBloquesLibres::get_bloque_libre() throw(ExcepArchCerrado, ExcepLeerBloque){
	int _return = ArchBloquesLibres::ERROR;
	
	//siempre trabajo con el ultimo bloque, esto me da la posibilidad de
	//ir truncando para que el archivo se achique
	Bloque * bloque = Buffer::get_instance()->get_bloque(*this, this->get_cant_bloques() - 1);
	
	unsigned int pos_inicial = 0;
	//si es el 0, salteo el tag que me cuenta la cantidad de bloques
	if( bloque->get_num_bloque() == 0)
		pos_inicial += sizeof(unsigned int);
	
	if( bloque->leer((char*)&_return, pos_inicial, _TAM_ELEMENTO_) ){
		//si pude leer comprimo	
		bloque->comprimir(pos_inicial, _TAM_ELEMENTO_);
		//si quedo vacio, trunco el archivo. Tener en cuenta que el bloque 0
		//nunca va a quedar vacio, asi que no hay problema
		if( bloque->get_tope() == 0 ){
			Buffer::get_instance()->invalidar_bloque(*this, bloque->get_num_bloque());
			ManejadorArchivos::get_instance()->truncar_arch(this->get_fd(), this->get_tam_bloque() * bloque->get_num_bloque() );
			this->cant_bloques--;
		}
		else
			//si no trunque, lo guardo en el buffer
			Buffer::get_instance()->guardar_bloque(*this, bloque);
	}	
	delete bloque;
	
	return _return;

}
TiposArchivo ArchBloquesLibres::get_tipo_archivo(){
	return NINGUNO;
}
unsigned int ArchBloquesLibres::get_espacio_libre()  throw(ExcepArchCerrado, ExcepLeerBloque){
	return 0;
}
